package com.framework.file;

import com.framework.exception.RRException;
import com.framework.exception.menu.RespCode;
import com.framework.redis.util.RedisUtil;
import com.framework.utils.AesUtil;
import com.framework.utils.ResponseUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.http.impl.execchain.RetryExec;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * 功能描述: 接口调用拦截器
 * @author ck
 * @date 2018/10/11 11:29
 */
public class SessionFile extends  HandlerInterceptorAdapter {

	private final String USER_URL = "user";

	private final String NOT_VAL_URL = "notValidate";

	/**
	 * 在业务处理器处理请求之前被调用
	 * @param request
	 * @param response
	 * @param o
	 * @return
	 * @throws Exception
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
		//请求地址
		String resUrl = request.getRequestURL().toString();
		int status = response.getStatus();
		if(status == 404){
			ResponseUtil.dealWithAjaxCustomReturn(response,"404","请求链接地址错误");
		}
		if(status == 500){
			ResponseUtil.dealWithAjaxCustomReturn(response,"500","服务器内部错误");
		}
		//不需要校验的地址
		boolean isNotVal = resUrl.contains(NOT_VAL_URL);
		if(isNotVal){
			return true;
		}
		boolean isUser = resUrl.contains(USER_URL);
			//需要校验加密参数
			RespCode respCode = getAllParam(request);
			String code = respCode.getCode();
			if(StringUtils.equals(code,"0000")){
				if(isUser){
					//校验需要登录的
					String token = request.getParameter("token");
					if(StringUtils.isBlank(token)){
						ResponseUtil.dealWithAjaxCustomReturn(response,"9000","token不能为空");
						return false;
					}
				}
				return true;
			}else {
				ResponseUtil.dealWithAjaxReturn(response, respCode);
				return false;
			}
		//return true;
	}

	//在业务处理器处理请求执行完成后
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
						   ModelAndView modelAndView) throws Exception {

	}

	/**
	 * 在DispatcherServlet完全处理完请求后被调用，可用于清理资源等
	 * @param httpServletRequest
	 * @param httpServletResponse
	 * @param o
	 * @param e
	 * @throws Exception
	 */
	@Override
	public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
	}

	/**
	 * 获取所有的参数,并且对参数进行签名校验
	 * @param request
	 */
	public static RespCode getAllParam(HttpServletRequest request){
		Long nowTime = System.currentTimeMillis();
		Map map = request.getParameterMap();
		Map<String,String> formMap = new HashMap<>();
		String encryption = "";
		Set keSet = map.entrySet();
		for(Iterator itr = keSet.iterator(); itr.hasNext();){
			Map.Entry me = (Map.Entry)itr.next();
			Object ok = me.getKey();
			Object ov = me.getValue();
			String[] value = new String[1];
			if(ov instanceof String[]){
				value = (String[])ov;
			}else{
				value[0] = ov.toString();
			}
			//对参数做验证
			for(int k = 0;k < value.length;k++){
				String param = (String) ok;
				String values = value[k];
				System.out.println("客户端参数为=================="+param+"-------"+values);
				if(StringUtils.equals(param, "sign")){
					encryption = values;
				}else{
					if(StringUtils.equals(param, "request_time")){
						long requestTime = Long.valueOf(values);//接口请求时间
						if(nowTime + 1000 * 60 < requestTime){
							return RespCode.ERROR_REQUEST_ENCRYPTION;
						}
						if(nowTime - requestTime > 1000 * 60){
							return RespCode.ERROR_REQUEST_OVER_TIME;
						}
					}
					if(StringUtils.equals(param, "token")){
						if(StringUtils.isBlank(values)){
							return RespCode.ERROR_TOKEN;
						}
					}
					formMap.put(param, values);
				}
			}
		}
		if(formMap == null){
			 throw new RRException("9000","加密参数不能为空");
		}
		//Unicode码从小到大排序（字典序）
		String paramSort = AesUtil.formatUrlMap(formMap, false, false);
		if(StringUtils.isBlank(paramSort)){
			return RespCode.ERROR_ENCRYPTION;
		}
		//校验加密是否正确
		String paramAes = AesUtil.aesEncrypt(paramSort);
		System.out.println("前端加密为=================="+encryption);
		System.out.println("服务端加密为=================="+paramAes);

		if(!StringUtils.equals(encryption, paramAes)){
			return RespCode.ENCRYPTION_ERROR;
		}
		return RespCode.SUCCESS;
	}

}
